/*
 * vs1011e.c
 *
 * Created: 04.01.2012 21:51:52
 *  Author: Luke
 */ 

#include <avr/io.h>
#include <util/delay.h>
#include "../sdfat-rr/uart.h"
#include "vs1011e.h"
#include "vs1011_defs.h"
#include "vs1011_regs.h"
#include "../sdfat-rr/uart.h"
#include "../drivers/SPI.h"

void vsInit(void)
{
	//dir = output
	VS_XRESET_DDR |= _BV(VS_XRESET_PIN);
	//output=off, keep VS1011 in reset
	VS_XRESET_PORT &= ~_BV(VS_XRESET_PIN);
	
	VS_XCS_DDR |= _BV(VS_XCS_PIN);
	VS_XCS_PORT |= _BV(VS_XCS_PIN);
	VS_XDCS_DDR |= _BV(VS_XDCS_PIN);
	VS_XDCS_PORT |= _BV(VS_XDCS_PIN);
	VS_DREQ_DDR &= ~_BV(VS_DREQ_PIN);
	VS_DREQ_PORT &= ~_BV(VS_DREQ_PIN);
	
	
}

void vsWriteRegister(uint8_t reg_addr, uint16_t reg_data)
{
    vsChipSelect();
    spiSendByteWait(VS_WRITE_INSTR);
    spiSendByteWait(reg_addr);
    spiSendWordWait(reg_data);
    vsChipDeSelect();
}

uint16_t vsReadRegister(uint8_t reg_addr)
{
    uint16_t result;
    
    vsChipSelect();
    spiSendByteWait(VS_READ_INSTR);
    spiSendByteWait(reg_addr);
    result = spiSendWordWait(0x00); //0x00 = dummy write
    vsChipDeSelect();
    
    return result;
}

void vsSineTest(void)
{
    uint16_t mode_reg;
    static uint8_t test_enabled = 0;
    
    if (test_enabled)
    {
        //Special sequence, see data sheet p.38
		vsChipSelectD();
        spiSendByteWait(0x45);
        spiSendByteWait(0x78);
        spiSendByteWait(0x69);
        spiSendByteWait(0x74);

        spiSendByteWait(0x00);
        spiSendByteWait(0x00);
        spiSendByteWait(0x00);
        spiSendByteWait(0x00);
		vsChipDeSelectD();
        test_enabled=0;
    }
    else
    {
        mode_reg = vsReadRegister(SCI_MODE);
		vsWriteRegister(SCI_MODE,_BV(SM_TESTS)|_BV(SM_SDINEW));
        /*vsChipSelect();
		_delay_ms(1);
		spiSendByteWait(0x02);
		spiSendByteWait(0x00);
		spiSendByteWait(0x08);
		spiSendByteWait(0x20);
        vsChipDeSelect();*/
		
        //special sequence, see data sheet p.38
		vsChipSelectD();
		_delay_ms(1);
        spiSendByteWait(0x53);
        spiSendByteWait(0xEF);
        spiSendByteWait(0x6E);
        spiSendByteWait(0x30); // <-- sine frequency control
        spiSendByteWait(0x00);
        spiSendByteWait(0x00);
        spiSendByteWait(0x00);
        spiSendByteWait(0x00);
		vsChipDeSelectD();
        test_enabled = 1;
    }
}


void vsChipDeSelect()
{
    VS_XCS_PORT |= _BV(VS_XCS_PIN);
}

void vsChipSelect()
{
    VS_XCS_PORT &= ~_BV(VS_XCS_PIN);
}


void vsChipDeSelectD()
{
    VS_XDCS_PORT |= _BV(VS_XDCS_PIN);
}

void vsChipSelectD()
{
    VS_XDCS_PORT &= ~_BV(VS_XDCS_PIN);
}

void vsUnReset()
{
    VS_XRESET_PORT |= _BV(VS_XRESET_PIN);
}

void vsReset()
{
    VS_XRESET_PORT &= ~_BV(VS_XRESET_PIN);
}

uint8_t vsGetDREQ(void)
{
	return (VS_DREQ_INP & _BV(VS_DREQ_PIN));
}

void vsPrepPlay(void)
{
	vsReadRegister(SCI_STATUS);
	vsWriteRegister(SCI_STATUS,0x0028);
	vsWriteRegister(SCI_MODE,0x0804);
	vsWriteRegister(SCI_CLOCKF, 12500);
}



void vsPlayBuffer(void)
{
	buffer_pos_ = 0;
	while(1)
	{
		uint8_t byte_counter;
		//wait for DREQ to indicate 32 byte of free FIFO
		while(!vsGetDREQ());
		
		
		vsChipSelectD();			
		for(byte_counter = 0; byte_counter<32; byte_counter++)
		{
			//uart_putc(playback_buffer_[buffer_pos_++]);	
			spiSendByteWait(playback_buffer_[buffer_pos_++]);
		}			
		vsChipDeSelectD();
		
		if (buffer_pos_ == BUFFERSIZE)
			break;
	}
}

